/********************************************************************
	Copyright (C) 2006-2008 Lensow
	http://www.lensow.com
	Created:	2008/06/14   13:39
	Filename: 	x:\Lensow\Loplayer\src\app\MediaFormats.cpp
	Author:		Dean

	Purpose:
*********************************************************************/

#include "stdafx.h"
#include "loplayer.h"
#include "MediaFormats.h"
#include <atlpath.h>
#include "..\dsutil\DSUtil.h"
#include "LanguageRes.h"

const LPCTSTR g_strPrefix = _T("loplayer.");

//
// CMediaFormatCategory
//

CMediaFormatCategory::CMediaFormatCategory()
		: m_fAudioOnly(false)
{
}

CMediaFormatCategory::CMediaFormatCategory(
	CString label, CString CommonExt, CAtlList<CString>& exts, bool fAudioOnly,
	CString specreqnote, engine_t engine)
{
	m_label = label;
	m_exts.AddTailList(&exts);
	m_backupexts.AddTailList(&m_exts);
	m_specreqnote = specreqnote;
	m_fAudioOnly = fAudioOnly;
	m_engine = engine;
	m_progid = g_strPrefix + CommonExt;
}

CMediaFormatCategory::CMediaFormatCategory(
	CString label, CString CommonExt, CString exts, bool fAudioOnly,
	CString specreqnote, engine_t engine)
{
	m_label = label;
	ExplodeMin(exts, m_exts, ' ');
	POSITION pos = m_exts.GetHeadPosition();
	while (pos) m_exts.GetNext(pos).TrimLeft('.');

	m_backupexts.AddTailList(&m_exts);
	m_specreqnote = specreqnote;
	m_fAudioOnly = fAudioOnly;
	m_engine = engine;
	m_progid = g_strPrefix + CommonExt;
}

CMediaFormatCategory::~CMediaFormatCategory()
{
}

void CMediaFormatCategory::UpdateData(bool fSave)
{
	if (fSave) {
		AfxGetApp()->WriteProfileString(_T("FileFormats"), m_label, GetExts(true));
	} else {
		SetExts(AfxGetApp()->GetProfileString(_T("FileFormats"), m_label, GetExts(true)));
	}
}

CMediaFormatCategory::CMediaFormatCategory(const CMediaFormatCategory& mfc)
{
	*this = mfc;
}

CMediaFormatCategory& CMediaFormatCategory::operator = (const CMediaFormatCategory & mfc)
{
	m_label = mfc.m_label;
	m_specreqnote = mfc.m_specreqnote;
	m_exts.RemoveAll();
	m_exts.AddTailList(&mfc.m_exts);
	m_backupexts.RemoveAll();
	m_backupexts.AddTailList(&mfc.m_backupexts);
	m_fAudioOnly = mfc.m_fAudioOnly;
	m_engine = mfc.m_engine;
	m_progid = mfc.m_progid;
	return *this;
}

void CMediaFormatCategory::RestoreDefaultExts()
{
	m_exts.RemoveAll();
	m_exts.AddTailList(&m_backupexts);
}

void CMediaFormatCategory::SetExts(CAtlList<CString>& exts)
{
	m_exts.RemoveAll();
	m_exts.AddTailList(&exts);
}

void CMediaFormatCategory::SetExts(CString exts)
{
	m_exts.RemoveAll();
	ExplodeMin(exts, m_exts, ' ');
	POSITION pos = m_exts.GetHeadPosition();
	while (pos) {
		POSITION cur = pos;
		CString& ext = m_exts.GetNext(pos);
		if (ext[0] == '\\') {
			m_engine = (engine_t)_tcstol(ext.TrimLeft('\\'), NULL, 10);
			m_exts.RemoveAt(cur);
		} else ext.TrimLeft('.');
	}
}

CString CMediaFormatCategory::GetFilter() const
{
	CString filter;
	POSITION pos = m_exts.GetHeadPosition();
	while (pos) filter += _T("*.") + m_exts.GetNext(pos) + _T(";");
	filter.TrimRight(_T(";")); // cheap...
	return(filter);
}

CString CMediaFormatCategory::GetExts( bool fAppendEngine /*= false*/ ) const
{
	CString exts = Implode(m_exts, ' ');
	if (fAppendEngine) exts += CString(_T(" \\")) + (TCHAR)(0x30 + (int)m_engine);
	return(exts);
}

CString CMediaFormatCategory::GetExtsWithPeriod( bool fAppendEngine /*= false*/ ) const
{
	CString exts;
	POSITION pos = m_exts.GetHeadPosition();
	while (pos) exts += _T(".") + m_exts.GetNext(pos) + _T(" ");
	exts.TrimRight(_T(" ")); // cheap...
	if (fAppendEngine) exts += CString(_T(" \\")) + (TCHAR)(0x30 + (int)m_engine);
	return(exts);
}

CString CMediaFormatCategory::GetBackupExtsWithPeriod( bool fAppendEngine /*= false*/ ) const
{
	CString exts;
	POSITION pos = m_backupexts.GetHeadPosition();
	while (pos) exts += _T(".") + m_backupexts.GetNext(pos) + _T(" ");
	exts.TrimRight(_T(" ")); // cheap...
	if (fAppendEngine) exts += CString(_T(" \\")) + (TCHAR)(0x30 + (int)m_engine);
	return(exts);
}

//
// 	CMediaFormats
//

CMediaFormats::CMediaFormats()
{
}

CMediaFormats::~CMediaFormats()
{
}

void CMediaFormats::UpdateData(bool fSave)
{
	if (fSave) {
		AfxGetApp()->WriteProfileString(_T("FileFormats"), NULL, NULL);

		AfxGetApp()->WriteProfileInt(_T("FileFormats"), _T("RtspHandler"), m_iRtspHandler);
		AfxGetApp()->WriteProfileInt(_T("FileFormats"), _T("RtspFileExtFirst"), m_fRtspFileExtFirst);
	} else {
		RemoveAll();
#define ADDFMT(f) Add(CMediaFormatCategory##f)
		ADDFMT((MultiStr(IDS_MEDIAFORMATS_0),	_T("wmv"),	_T("wmv wmp wm asf")));
		ADDFMT((MultiStr(IDS_MEDIAFORMATS_1),	_T("wma"),	_T("wma"), true));
		ADDFMT((MultiStr(IDS_AG_VIDEO_FILE),	_T("avi"),	_T("avi")));
		ADDFMT((MultiStr(IDS_AG_AUDIO_FILE),	_T("wav"),	_T("wav"), true));
		ADDFMT((MultiStr(IDS_MEDIAFORMATS_4),	_T("mpg"),	_T("mpg mpeg mpe m1v m2v mpv2 mp2v dat ts tp tpr pva pss evo m2ts")));
		ADDFMT((MultiStr(IDS_MEDIAFORMATS_5),	_T("mpa"),	_T("mpa mp2 m1a m2a"), true));
		ADDFMT((MultiStr(IDS_AG_DVD_FILE),		_T("dvdf"),	_T("vob ifo")));
		ADDFMT((MultiStr(IDS_MEDIAFORMATS_7),		_T("dvda"),	_T("ac3 dts"), true));
		ADDFMT((_T("MP3 Format Sound"),			_T("mp3"),	_T("mp3"), true));
		ADDFMT((MultiStr(IDS_AG_MIDI_FILE),		_T("mid"),	_T("mid midi rmi"), true));
		ADDFMT((MultiStr(IDS_MEDIAFORMATS_9),		_T("ivf"),	_T("ivf")));
		ADDFMT((_T("AIFF Format Sound"),		_T("aiff"),	_T("aif aifc aiff"), true));
		ADDFMT((_T("AU Format Sound"),			_T("au"),	_T("au snd"), true));
		ADDFMT((MultiStr(IDS_MEDIAFORMATS_10),	_T("ogm"),	_T("ogm")));
		ADDFMT((MultiStr(IDS_MEDIAFORMATS_11),	_T("ogg"),	_T("ogg"), true));
		ADDFMT((_T("CD Audio Track"),			_T("cda"),	_T("cda"), true, MultiStr(IDS_MEDIAFORMATS_12)));
		ADDFMT((MultiStr(IDS_AG_FLIC_FILE),		_T("flic"),	_T("fli flc flic")));
		ADDFMT((MultiStr(IDS_MEDIAFORMATS_14),	_T("d2v"),	_T("d2v")));
		ADDFMT((MultiStr(IDS_AG_MPEG4_FILE),		_T("mp4"),	_T("mp4 m4v hdmov 3gp 3gpp")));
		ADDFMT((MultiStr(IDS_MEDIAFORMATS_16),	_T("aac"),	_T("m4a m4b aac"), true));
		ADDFMT((MultiStr(IDS_MEDIAFORMATS_17),	_T("mkv"),	_T("mkv")));
		ADDFMT((MultiStr(IDS_MEDIAFORMATS_18),	_T("mka"),	_T("mka"), true));
		ADDFMT((MultiStr(IDS_MEDIAFORMATS_19),	_T("bik"),	_T("smk bik"), false, _T("smackw32/binkw32.dll in dll path")));
		ADDFMT((MultiStr(IDS_AG_RATDVD_FILE),		_T("ratdvd"), _T("ratdvd"), false, _T("ratdvd media file")));
		ADDFMT((MultiStr(IDS_MEDIAFORMATS_21),	_T("roq"),	_T("roq"), false));
		ADDFMT((MultiStr(IDS_MEDIAFORMATS_22),	_T("rm"),	_T("rm ram rpm rmm rnx"), false, _T("RealPlayer or Real Alternative")));
		ADDFMT((MultiStr(IDS_MEDIAFORMATS_23),	_T("ra"),	_T("ra"), true, _T("RealPlayer or Real Alternative")));
		ADDFMT((MultiStr(IDS_MEDIAFORMATS_24),	_T("rt"),	_T("rt rp smi smil"), false, _T("RealPlayer or Real Alternative"), RealMedia));
//		ADDFMT((MultiStr(IDS_MEDIAFORMATS_25),	_T("drc"),	_T("drc"), false));
		ADDFMT((MultiStr(IDS_MEDIAFORMATS_26),	_T("dsm"),	_T("dsm dsv dsa dss")));
//		ADDFMT((MultiStr(IDS_AG_MUSEPACK_FILE),	_T("mpc"),	_T("mpc"), true));
		ADDFMT((MultiStr(IDS_MEDIAFORMATS_28),	_T("flv"),	_T("flv")));
		ADDFMT((MultiStr(IDS_MEDIAFORMATS_29),	_T("swf"),	_T("swf"), false, _T("ShockWave ActiveX control"), ShockWave));
		ADDFMT((MultiStr(IDS_MEDIAFORMATS_30),	_T("mov"),	_T("mov qt amr 3g2 3gp2"), false, _T("QuickTime (Alternative)"), QuickTime));
		ADDFMT((MultiStr(IDS_AG_IMAGE_FILE),		_T("jpeg"),	_T("jpeg jpg bmp gif pic png dib tiff tif")));
		ADDFMT((MultiStr(IDS_AG_PLAYLIST_FILE),	_T("pls"),	_T("asx m3u pls wvx wax wmx mpcpl")));
		ADDFMT((MultiStr(IDS_AG_OTHER),			_T("other"), _T("divx vp6 rmvb amv")));
#undef ADDFMT

		m_iRtspHandler = (engine_t)AfxGetApp()->GetProfileInt(_T("FileFormats"), _T("RtspHandler"), (int)RealMedia);
		m_fRtspFileExtFirst = !!AfxGetApp()->GetProfileInt(_T("FileFormats"), _T("RtspFileExtFirst"), 1);
	}

	for (int i = 0; i < GetCount(); i++)
		GetAt(i).UpdateData(fSave);
}

engine_t CMediaFormats::GetRtspHandler( bool& fRtspFileExtFirst ) const
{
	fRtspFileExtFirst = m_fRtspFileExtFirst;
	return m_iRtspHandler;
}

void CMediaFormats::SetRtspHandler(engine_t e, bool fRtspFileExtFirst)
{
	m_iRtspHandler = e;
	m_fRtspFileExtFirst = fRtspFileExtFirst;
}

bool CMediaFormats::IsUsingEngine( CString path, engine_t e ) const
{
	return(GetEngine(path) == e);
}

engine_t CMediaFormats::GetEngine(LPCTSTR lpszPath) const
{
	CString path(lpszPath);
	path.Trim().MakeLower();

	if (!m_fRtspFileExtFirst && path.Find(_T("rtsp://")) == 0)
		return m_iRtspHandler;

	CString ext = CPath(path).GetExtension();
	ext.MakeLower();
	if (!ext.IsEmpty()) {
		if (path.Find(_T("rtsp://")) == 0) {
			if (ext == _T(".ram") || ext == _T(".rm") || ext == _T(".ra"))
				return RealMedia;
			if (ext == _T(".qt") || ext == _T(".mov"))
				return QuickTime;
		}

		for (int i = 0; i < GetCount(); i++) {
			const CMediaFormatCategory& mfc = GetAt(i);
			if (mfc.FindExt(ext))
				return mfc.GetEngineType();
		}
	}

	if (m_fRtspFileExtFirst && path.Find(_T("rtsp://")) == 0)
		return m_iRtspHandler;

	return DirectShow;
}

bool CMediaFormats::FindExt( CString ext, bool fAudioOnly /*= false*/ ) const
{
	ext.TrimLeft(_T("."));

	if (!ext.IsEmpty()) {
		for (int i = 0; i < GetCount(); i++) {
			const CMediaFormatCategory& mfc = GetAt(i);
			if ((!fAudioOnly || mfc.IsAudioOnly()) && mfc.FindExt(ext))
				return(true);
		}
	}

	return(false);
}

void CMediaFormats::GetFilter( CString& filter, CStringArray& mask ) const
{
	CString		strTemp;

	filter += MultiStr(IDS_MEDIAFORMATS_34);
	mask.Add(_T(""));

	for (int i = 0; i < GetCount(); i++) {
		strTemp  = GetAt(i).GetFilter() + _T(";");;
		mask[0] += strTemp;
		filter  += strTemp;
	}
	mask[0].TrimRight(_T(";"));
	filter.TrimRight(_T(";"));
	filter += _T("|");

	for (int i = 0; i < GetCount(); i++) {
		const CMediaFormatCategory& mfc = GetAt(i);
		filter += mfc.GetLabel() + _T("|" + GetAt(i).GetFilter() + _T("|"));
		mask.Add(mfc.GetFilter());
	}

	filter += MultiStr(IDS_MEDIAFORMATS_35);
	mask.Add(_T("*.*"));

	filter += _T("|");
}

void CMediaFormats::GetAudioFilter( CString& filter, CStringArray& mask ) const
{
	CString		strTemp;
	filter += MultiStr(IDS_MEDIAFORMATS_36);
	mask.Add(_T(""));

	for (int i = 0; i < GetCount(); i++) {
		const CMediaFormatCategory& mfc = GetAt(i);
		if (!mfc.IsAudioOnly() || mfc.GetEngineType() != DirectShow) continue;
		strTemp  = GetAt(i).GetFilter() + _T(";");
		mask[0] += strTemp;
		filter  += strTemp;
	}

	mask[0].TrimRight(_T(";"));
	filter.TrimRight(_T(";"));
	filter += _T("|");

	for (int i = 0; i < GetCount(); i++) {
		const CMediaFormatCategory& mfc = GetAt(i);
		if (!mfc.IsAudioOnly() || mfc.GetEngineType() != DirectShow) continue;
		filter += mfc.GetLabel() + _T("|") + GetAt(i).GetFilter() + _T("|");
		mask.Add(mfc.GetFilter());
	}

	filter += MultiStr(IDS_MEDIAFORMATS_35);
	mask.Add(_T("*.*"));

	filter += _T("|");
}
